<?php

namespace App\Http\Model;

use App\Lib\Publisher;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use function PHPSTORM_META\elementType;


class FinanceRechargeOrder extends Base
{
    //订单状态status
    const STATUS_OF_CREATED = 0;//订单已创建，还未支付
    const STATUS_OF_SUCCESS = 1;//已支付
    const STATUS_OF_REFUNDED = 2;//已退款

    protected $table = 'finance_recharge_order';
    public $timestamps = false;
    private $redis_apple_md5 = 'FINANCE:RECHARGE:APPLE:MD5';
    private $redis_apple_transactionid = 'FINANCE:RECHARGE:APPLE:TRANSACTIONID';

    private $redisAlipayH5White = 'FINANCE:RECHARGE:ALIPAYH5:WHITE';

    private $redisAlipayUserId = 'FINANCE:RECHARGE:ALIPUSERID:%d';


    protected $table_recharge_user = 'finance_recharge_user';
    protected $first_recharge_user_log_model='first_recharge_user_log';//用户首充记录表-关联许愿池活动道具表
    protected $user_table = 'user';//用户表
    protected $payOrderCountRedisKey = 'PAY:ORDER:COUNT:USER:';//string 用户下订单次数 PAY:ORDER:COUNT:USER:{int}


    protected $RechargeWcupOrder = 'RECHARGE_WCUP_ORDER';

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    public function setRechargeWcupOrder($orderId){

        return Redis::HSET($this->RechargeWcupOrder, $orderId, time());
    }

    public function checkRechargeWcupOrder($orderId){

        return (int)Redis::HGET($this->RechargeWcupOrder, $orderId);
    }

    /**
     * 添加支付订单
     * @param $order_sn
     * @param $user_id
     * @param $rule_id
     * @param $diamond_amount
     * @param $price
     * @param $pay_type
     * @param $channel_id 渠道商ID
     * @param $pearlAmount 珍珠数量
     * @param $rechargeType 充值类型 0=钻石,1=珍珠
     * @return int
     */
    public function create_order($order_sn, $user_id, $rule_id, $diamond_amount, $price, $pay_type, $channel_id,$pearlAmount = 0,$rechargeType = 0, $mch_id=0,$first_recharge_id){
        $time = time();
        $data['order_sn'] = $order_sn;
        $data['user_id'] = $user_id;
        $data['rule_id'] = $rule_id;
        $data['diamond_amount'] = $diamond_amount;
        $data['price'] = $price;
        $data['pay_type'] = $pay_type;
        $data['create_timestamp'] = time();
        $data['channel_id'] = $channel_id;
        $data['recharge_type'] = $rechargeType;
        $data['request_ip'] = !empty(client_ip()) ? ip2long(client_ip()) : 0;
        $data['mch_id'] = $mch_id;
        $data['first_recharge_id'] = $first_recharge_id;//首冲礼包ID
        $result = DB::table($this->table)->insertGetId($data);
        //记录用户下订单时间redis处理充值黑名单逻辑,未支付3次以上加入黑名单
        if(!empty(Redis::get($this->payOrderCountRedisKey.$user_id.':PAYTYPE:'.$pay_type))){
            Redis::INCRBY($this->payOrderCountRedisKey.$user_id.':PAYTYPE:'.$pay_type,1);
        }else{
            Redis::INCRBY($this->payOrderCountRedisKey.$user_id.':PAYTYPE:'.$pay_type,1);
            $endTime = 300; //下单时间300秒
            Redis::EXPIRE($this->payOrderCountRedisKey.$user_id.':PAYTYPE:'.$pay_type,$endTime);
        }
        return $result;
    }
    
    //获取订单order_id
    public function getOrder($order_id)
    {
        $condition['order_id'] = $order_id;
        $fields = ['order_id', 'order_sn', 'user_id', 'rule_id', 'diamond_amount', 'price', 'pay_type', 'status','pearl_amount','recharge_type','first_recharge_id'];
        $document = DB::table($this->table)->where($condition)->first($fields);
        $ret = self::objToArray($document);
        return $ret;
    }
    
    //获取订单order_sn
    public function getOrderBySn($order_sn)
    {
        $condition['order_sn'] = $order_sn;
        $fields = ['order_id', 'order_sn', 'user_id', 'rule_id', 'diamond_amount', 'price', 'pay_type', 'status','pearl_amount','recharge_type','first_recharge_id'];
        $document = DB::table($this->table)->where($condition)->first($fields);
        $ret = self::objToArray($document);
        return $ret;
    }


    /**
     * 获取订单 $out_order_sn
     * @param $out_order_sn
     * @return mixed|null
     */
    public function getOrderByOutsn($out_order_sn){
        $condition['out_trade_sn'] = $out_order_sn;
        $fields = ['order_id', 'order_sn', 'user_id', 'rule_id', 'diamond_amount', 'price', 'pay_type', 'status','pearl_amount','recharge_type','first_recharge_id'];
        $document = DB::table($this->table)->where($condition)->first($fields);
        if ($document == null){
            return null;
        }
        $ret = self::objToArray($document);
        return $ret;
    }
    
    //查看用户下成功充值的单数
    public function isFristRecharge($userid)
    {
        $count = DB::table($this->table)->where(['user_id'=>$userid,'status'=>1])->count();
        $data['orderinfo'] = [];
        $data['count'] = $count;
        //查看注册时间是否是新用户
        $isNewUser = DB::table($this->user_table)->where('user_id',$userid)->first();
        $isNewUser = self::objToArray($isNewUser);
        //是否在,在7天内是新用户
        $nowDate = Carbon::now()->toDateString();
        $diffDate =  Carbon::parse($isNewUser['create_time'])->toDateString();
        $compare = Carbon::parse($diffDate)->diffInDays($nowDate,true);
        if($count == 1 && $compare <=7)
        {
            $info = DB::table($this->table)->where(['user_id'=>$userid,'status'=>1])->first(['order_id', 'order_sn', 'user_id', 'rule_id', 'diamond_amount', 'price', 'pay_type', 'status','pearl_amount','recharge_type','first_recharge_id']);
            $info = self::objToArray($info);
            $data['orderinfo'] = $info;
        }
        return $data;
    }

    //更改订单状态
    public function changeOrderStatus($order_sn, $out_trade_sn)
    {
        $condition['order_sn'] = $order_sn;
        $ret = DB::table($this->table)->where($condition)->update(['status' => 1, 'out_trade_sn' => $out_trade_sn, 'pay_timestamp' => time()]);

        return $ret;
    }

    //更改订单钻石数
    public function changeOrderDiamondAmount($order_sn, $diamond_amount)
    {
        $condition['order_sn'] = $order_sn;
        $ret = DB::table($this->table)->where($condition)->update(['diamond_amount' => $diamond_amount]);

        return $ret;
    }

    //订单支付成功通知MQ
    public function orderPaySuccessToMQ($order_sn, $userId)
    {
        $condition['order_sn'] = $order_sn;
        $getOrderData = DB::table($this->table)->where($condition)->first();
        $getOrderData = self::objToArray($getOrderData);

        // 进入队列通知活动端
        $publishObject = Publisher::getInstance();
        $getOrderData['mqtype'] = 5;
        $publishObject->requestData = [
            'queue_route'=>'global.finance.recharge',
            'data'=>$getOrderData,
        ];

        //用户房间banner
        $publishObject->publisher();
        $publishObject->requestData = [
            'queue_route'=>'global.userroombanner',
            'data'=>['user_ids'=>[$userId], 'type'=>1],
        ];
        $publishObject->publisher();

        return 1;
    }

    /**
     * 获取用户订单
     * @param $user_id
     * @param $rule_id
     * @param int $pay_type
     * @param int $status
     */
    public function getOrderByUser($user_id, $rule_id, $pay_type = 2, $status = 0, $start_time = 0, $end_time = 0){
        $condition['user_id'] = $user_id;
        $condition['rule_id'] = $rule_id;
        $condition['pay_type'] = $pay_type;
        $condition['status'] = $status;
        $fields = ['order_id', 'order_sn', 'user_id', 'rule_id', 'diamond_amount', 'price', 'pay_type', 'status','pearl_amount','recharge_type','first_recharge_id'];
        $document = null;
        if (empty($start_time)){
            $document = DB::table($this->table)->where($condition)->first($fields);
        }else{
            $document = DB::table($this->table)
                ->where($condition)
                ->where('create_timestamp', '>', $start_time)
                ->where('create_timestamp', '<', $end_time)
                ->first($fields);
        }

        if (empty($document)){
            return null;
        }
        $ret = self::objToArray($document);
        return $ret;
    }

    public function setAppleReceipt($user_id, $receipt_data){
        Redis::HSET($this->redis_apple_md5, $user_id.md5($receipt_data), time());
    }

    public function hasAppleReceipt($user_id, $receipt_data){
        $ret = Redis::HGET($this->redis_apple_md5, $user_id.md5($receipt_data));
        if (empty($ret)){
            return false;
        }
        return true;
    }

    public function hasAppleReceiptInc($user_id, $receipt_data){
        return Redis::HINCRBY($this->redis_apple_md5, $user_id.md5($receipt_data), 1);
    }

    public function hasAppleTransactionIdInc($transaction_id){
        return Redis::HINCRBY($this->redis_apple_transactionid, $transaction_id, 1);
    }

    /**
     * 支付宝H5管控白名单
     * @param $userId
     * @return mixed
     */
    public function aliPayH5White($userId){
        return Redis::HEXISTS($this->redisAlipayH5White, $userId);
    }


    /**
     * 支付宝H5白名单获取所有用户数组
     * @return mixed
     */
    public function getAliPayH5WhiteArr(){
        return Redis::HKEYS($this->redisAlipayH5White);
    }

    /**
     * 支付宝H5白名单删除用户
     * @param $userId
     * @return mixed
     */
    public function delAliPayH5White($userId){
        return Redis::HDEL($this->redisAlipayH5White, $userId);
    }


    /**
     * 支付宝H5白名单添加用户
     * @param $userId
     * @return mixed
     */
    public function addAliPayH5White($userId){
        return Redis::HSET($this->redisAlipayH5White, $userId, time());
    }


    /**
     * 支付总金额
     * @param $userId
     * @param $payType
     * @param $startTime
     * @param $endTime
     * @return mixed
     */
    public function getPaySumPrice($userId, $payType, $startTime, $endTime){

        $condition['user_id'] = $userId;
        $condition['pay_type'] = $payType;
        $condition['status'] = 1;

        $sum = DB::table($this->table)
            ->where($condition)
            ->where('create_timestamp', '>', $startTime)
            ->where('create_timestamp', '<', $endTime)
            ->sum('price');
        return $sum ?? 0;
    }



    /**
     * 支付次数
     * @param $userId
     * @param $payType
     * @param $startTime
     * @param $endTime
     * @return mixed
     */
    public function getPayCount($userId, $payType){

        $condition['user_id'] = $userId;
        $condition['pay_type'] = $payType;
        $condition['status'] = 1;

        $count = DB::table($this->table)
            ->where($condition)
            ->count();
        return $count ?? 0;
    }


    public function getAllPaySumPrice($payType, $startTime, $endTime){

        $condition['pay_type'] = $payType;
        $condition['status'] = 1;

        $sum = DB::table($this->table)
            ->where($condition)
            ->where('create_timestamp', '>', $startTime)
            ->where('create_timestamp', '<', $endTime)
            ->sum('price');
        return $sum ?? 0;
    }

    public function getAllPaySumCount($payType, $startTime, $endTime){

        $condition['pay_type'] = $payType;
        $condition['status'] = 1;

        $count = DB::table($this->table)
            ->where($condition)
            ->where('create_timestamp', '>', $startTime)
            ->where('create_timestamp', '<', $endTime)
            ->count();
        return $count ?? 0;
    }


    /**
     * 用户充值金额
     * @param $userId
     * @param $startTime
     * @param $endTime
     * @return int|mixed
     */
    public function getUserPayPrice($userId, $startTime, $endTime)
    {
        $condition['user_id'] = $userId;
        $condition['status'] = 1;

        $sum = DB::table($this->table)
            ->where($condition)
            ->where('create_timestamp', '>', $startTime)
            ->where('create_timestamp', '<', $endTime)
            ->sum('price');
        return $sum ?? 0;
    }


    /**
     * 设置支付宝用户ID
     * @param $userId
     * @param $aliUserId
     * @return mixed
     */
    public function setAliUserId($userId, $aliUserId){
        $key = sprintf($this->redisAlipayUserId, $userId);
        return Redis::hset($key, $aliUserId, time());
    }

    /**
     * 获取支付宝ID数量
     * @param $userId
     * @return mixed
     */
    public function getAliUserIdCount($userId){
        $key = sprintf($this->redisAlipayUserId, $userId);
        return Redis::HLEN($key);
    }


    /**
     * 获取用户组订单数量
     *
     * @param array $userIdArray 用户ID组
     * @param int $payType 订单类型
     * @param int $startTime 开始时间戳
     * @param int $endTime 结束时间戳
     * @return int
     * */
    public function getOrderCountByUserIds($userIdArray, $payType, $startTime = null, $endTime = null)
    {
        if (empty($userIdArray)) {
            return 0;
        }

        $db = DB::table($this->table)->whereIn('user_id', $userIdArray)->where(['status' => 1, 'pay_type' => $payType]);
        if (is_numeric($startTime) and is_numeric($endTime)) {
            $db->whereBetween('create_timestamp', [$startTime, $endTime]);
        }

        return $db->count();
    }

    /**获取用户充值次数
     * @param $user_id
     * @return int
     */
    public function getPayNumByUserId($user_id){
        $condition['user_id'] = $user_id;
        $condition['status'] = 1;
        $count = DB::table($this->table)
            ->where($condition)
            ->count();
        return $count ?? 0;
    }

    /**
     * 设置微信h5支付referer
     * @param $key
     * @param $url
     */
    public function setWeixinReferer($key, $url)
    {
        Redis::SET('FINACE:PAY:WEIXIN:REFERER:' . $key, $url, 'EX', 5);
    }


    /**
     * 获取微信h5支付referer
     * @param $key
     * @return mixed
     */
    public function getWeixinReferer($key)
    {
        return Redis::GET('FINACE:PAY:WEIXIN:REFERER:' . $key);
    }
    /**设置充值用历史记录
     * @param $params
     */
    public function setRechargeUser($params){
        DB::table($this->table_recharge_user)->insertGetId($params);
    }

    /**获取充值用历史记录
     * @param $user_id
     * @return array
     */
    public function getRechargeUser($user_id){
        $res = DB::table($this->table_recharge_user)
            ->where('user_id' ,$user_id)
            ->get(['recharge_user_id']);
        $res = $this->objToArray($res);
        return empty($res) ? [] : array_unique(array_column($res ,'recharge_user_id'));
    }

    /**
     * @author zxiaofee
     * @desc 检查用户是否是首次付费 首次付费上报用
     * @param $user_id int
     * @return bool
     * @date 2022.02.16
     */
    public function isFirstRecharge($user_id){
        $count = DB::table($this->table)
            ->where('user_id' ,$user_id)
            ->where('status', 1)
            ->limit(2)->count();
        return 0 < $count && $count < 2;
    }

    public function getTenMinPayOrdersByUids($uids){
        $orders = DB::table($this->table)
            ->select(['user_id', 'price', 'create_time'])
            ->whereIn('user_id' ,$uids)
            ->where('status', 1)
            ->where('price', '>', 9800)
            ->get();
        $orders = $this->objToArray($orders);
        return $orders;
    }

    public function getTenMinExceptionOrders(){
        $timestart = time() - 600;
        $orders = DB::table($this->table)
            ->selectRaw('user_id')
            ->selectRaw('count(*) as total_num')
            ->selectRaw('sum(price) as total_amount')
            ->where('create_timestamp','>' ,$timestart)
            ->where('status', 1)
            ->where('price', '>=', 29800)
            ->groupBy(['user_id'])
            ->get();
        $orders = $this->objToArray($orders);
        return $orders;
    }

    //获取用户24小时内消费总额
    public function getRechargeTotal24($userId){
        $timeStart = strtotime(date('Y-m-d'));
        return DB::table($this->table)
            ->where('create_timestamp','>' ,$timeStart)
            ->where('user_id', $userId)
            ->where('status', 1)
            ->sum("price");
    }

    //获取用户充值总额
    public function getRechargeTotal($userId) {
        return DB::table($this->table)
            ->where('user_id', $userId)
            ->where('status', 1)
            ->sum("price");
    }

    //获取用户充值总钻石数
    public function getRechargeDiamondTotal($userId){
        return DB::table($this->table)
        ->where('user_id', $userId)
        ->where('status', 1)
        ->sum("diamond_amount");
    }
    //认证用户第一次充值总钻石数
    public function getRechargeDiamondTotal2($userId){
        return DB::table($this->table)
            ->where('user_id', $userId)
//        ->where('status', 1)
            ->sum("diamond_amount");
    }

    public function getLoginRechargeConsumeTimeline($userId){
        $sqlStr =<<<sql
SELECT * from (
SELECT '1' as type, `guid`,  FROM_UNIXTIME(`time`,'%Y-%m-%d %H:%i:%s') as time, '' as to_user_id, '' as price from `zb_user_login_log` WHERE `user_id`=%d 
UNION ALL 
SELECT '2' as type, '' as guid,   FROM_UNIXTIME(`create_timestamp`,'%Y-%m-%d %H:%i:%s') as time, '' as to_user_id, price  from `zb_finance_recharge_order` WHERE `user_id`=%d
UNION ALL 
SELECT '3' as type , '' as guid,  FROM_UNIXTIME( `change_timestamp`, '%Y-%m-%d %H:%i:%s') as time,  `user_id` as to_user_id, (`gift_num` * `gift_price`) as price from `zb_gift_stream` WHERE `from_user_id`=%d
) t ORDER BY time asc limit 100
sql;
        $sqlStr = sprintf($sqlStr, $userId, $userId, $userId);
        return DB::select($sqlStr);
    }

    //获取用户充值总额
    public function getTodayRechargeTotalByPayTypeAndUserId($userId, $payTypes) {
        $curTime = strtotime(date("Y-m-d"),time());
        return DB::table($this->table)
            ->where('user_id', $userId)
            ->whereIn('pay_type', $payTypes)
            ->where('status', 1)
            ->where('pay_timestamp', '>', $curTime)
            ->sum("price");
    }
    /**
     * 获取设备是否领取过许愿池券
     */
    public function getIssetTicketLog($guid)
    {
        $status = DB::table($this->first_recharge_user_log_model)->where('guid',$guid)->exists();
        return $status;
    }
    /**
     * 更新新用户获得许愿池券
     */
    public function updateFirstTicketLog($userid,$guid)
    {
        $update['guid'] = $guid;
        $ticketid = DB::table("luck_draw_user_prop")->where(['user_id'=>$userid,'luck_id'=>1000,'avail'=>1,'deleted'=>0])->first(['id']);
        $ticketid = $this->objToArray($ticketid);
        $update['luck_draw_user_prop_id'] = $ticketid['id'];
        $update['has_ticket'] = 1; //领取数量
        $status = DB::table($this->first_recharge_user_log_model)->where('user_id',$userid)->update($update);
        return $status;
    }
    /**
     * 记录新用户获得许愿池券log
     * 
     */
    public function writeFirstRechargeLog($data)
    {
       $res = DB::table($this->first_recharge_user_log_model)->insert($data);
       return $res;
    }

    /**
     * 获取用户组订单数量
     *
     * @param array $userIdArray 用户ID组
     * @param int $startTime 开始时间戳
     * @param int $endTime 结束时间戳
     * @return int
     * */
    public function getOrderCountByUser($userIdArray, $startTime = null, $endTime = null)
    {
        if (empty($userIdArray)) {
            return 0;
        }

        $db = DB::table($this->table)->whereIn('user_id', $userIdArray)->where(['status' => 1]);
        if (is_numeric($startTime) and is_numeric($endTime)) {
            $db->whereBetween('create_timestamp', [$startTime, $endTime]);
        }

        return $db->count();
    }
    //获取充值规则
    public function getDiamondRule($rule_id)
    {
        $condition['rule_id'] = $rule_id;
        $fields = ['rule_id','price','diamond_amount','plat_type', 'apple_product_id', 'diamond_extra_num'];
        $document = DB::table('finance_diamond_pay_rule')->where($condition)->first($fields);
        $ret = self::objToArray($document);
        return $ret;
    }
}
